<?php

/**
 * @package Bike
 * @subpackage Storage
 */

/**
 * Base Storage class
 * @author Chrome
 * @package Bike
 * @subpackage Storage
 */
class Bike_Storage_Base implements Bike_Storage_IBase {

	/**
	 * Table prefix
	 * @var string
	 */
	protected $prefix = '';
	
	/**
	 * Name of table
	 * @var string
	 */
	protected $name = '';

	/**
	 * Readable connection
	 * @var Bike_Db_Idb
	 */
	protected $readableConnection = null;
	
	/**
	 * Writable connection
	 * @var Bike_Db_Idb
	 */
	protected $writableConnection = null;

	/**
	 * Default fields
	 * @var array
	 */
	protected $fields = array('id' => array('type' => 'integer', 'title' => 'Id of record'));

	/**
	 * Constructor
	 * @param array $fields storage fields
	 */
	public function __construct(array $fields){
		foreach($fields as $label => $fieldData){
			$this->fields[$label] = $fieldData;
		}
	}

	/* (non-PHPdoc)
	 * @see Bike_Storage_IBase::getFields()
	 */
	public function getFields(){
		return $this->fields;
	}

	/**
	 * Filter fields and remove excessive data
	 * @param array $data
	 * @return array
	 */
	protected function prepareData(array $data){
		$result = array();
		foreach($this->getFields() as $label => $fieldData){
			if(isset($data[$label])){
				switch($fieldData['type']){
					case 'integer':
					case 'int':
						$result[$label] = intval($data[$label]);
						break;
					case 'password':
						$result[$label] = md5($data[$label]);
						break;
					default:
						$result[$label] = $data[$label];
						break;
				}
			}
		}
		return $result;
	}

	/* (non-PHPdoc)
	 * @see Bike_Storage_IBase::setReadableConnection()
	 */
	public function setReadableConnection(Bike_Db_Idb $connection) {
		$this->readableConnection = $connection;
		return true;
	}

	/* (non-PHPdoc)
	 * @see Bike_Storage_IBase::setWritableConnection()
	 */
	public function setWritableConnection(Bike_Db_Idb $connection) {
		$this->writableConnection = $connection;
		return true;
	}

	/**
	 * @see Bike_Storage_IBase::getReadableConnection()
	 * @throws Bike_Storage_Exception
	 */
	public function getReadableConnection() {
		if(!empty($this->readableConnection)){
			return $this->readableConnection;
		}
		throw new Bike_Storage_Exception('Connection is not set', Bike_Storage_Exception::READABLE_CONNECTION_IS_NOT_SET);
	}

	/**
	 * @see Bike_Storage_IBase::getWritableConnection()
	 * @throws Bike_Storage_Exception
	 */
	public function getWritableConnection() {
		if(!empty($this->writableConnection)){
			return $this->writableConnection;
		}
		throw new Bike_Storage_Exception('Connection is not set', Bike_Storage_Exception::WRITABLE_CONNECTION_IS_NOT_SET);
	}

	/* (non-PHPdoc)
	 * @see Bike_Storage_IBase::setStorageName()
	 */
	public function setStorageName($storageName){
		$this->name = $storageName;
		return true;
	}

	/**
	 * Get name of storage
	 * @return string
	 */
	public function getStorageName(){
		return $this->name;
	}

	/**
	 * @see Bike_Storage_IBase::getRecordsByConditions()
	 * @throws Bike_Storage_Exception
	 */
	public function getRecordsByConditions(array $filters, $offset = 0, $limit = 20, array $sortings = array()){
		if(empty($this->name)){
			throw new Bike_Storage_Exception('Set storage name first!', Bike_Storage_Exception::STORAGE_NAME_IS_NOT_SET);
		}
		if(empty($this->readableConnection)){
			$this->setReadableConnection(Bike_Service_Locator::getService('Storage')->getReadableConnection());
		}
	}

	/**
	 * @see Bike_Storage_IBase::updateRecord()
	 * @throws Bike_Storage_Exception
	 */
	public function updateRecord($id, array $data){
		if(empty($id) || empty($data)){
			throw new Bike_Storage_Exception('Incorrect arguments passed', Bike_Storage_Exception::INCORRECT_ARGUMENTS_PASSED);
		}
		if(empty($this->name)){
			throw new Bike_Storage_Exception('Set storage name first!', Bike_Storage_Exception::STORAGE_NAME_IS_NOT_SET);
		}
		if(empty($this->writableConnection)){
			$this->setWritableConnection(Bike_Service_Locator::getService('Storage')->getWritableConnection());
		}
	}

	/**
	 * @see Bike_Storage_IBase::insertRecord()
	 * @throws Bike_Storage_Exception
	 */
	public function insertRecord(array $data){
		if(empty($data)){
			throw new Bike_Storage_Exception('Incorrect arguments passed', Bike_Storage_Exception::INCORRECT_ARGUMENTS_PASSED);
		}
		if(empty($this->name)){
			throw new Bike_Storage_Exception('Set storage name first!', Bike_Storage_Exception::STORAGE_NAME_IS_NOT_SET);
		}
		if(empty($this->writableConnection)){
			$this->setWritableConnection(Bike_Service_Locator::getService('Storage')->getWritableConnection());
		}
	}

	/**
	 * @see Bike_Storage_IBase::deleteRecord()
	 * @throws Bike_Storage_Exception
	 */
	public function deleteRecord($id){
		if(empty($id)){
			throw new Bike_Storage_Exception('Incorrect arguments passed', Bike_Storage_Exception::INCORRECT_ARGUMENTS_PASSED);
		}
		if(empty($this->name)){
			throw new Bike_Storage_Exception('Set storage name first!', Bike_Storage_Exception::STORAGE_NAME_IS_NOT_SET);
		}
		if(empty($this->writableConnection)){
			$this->setWritableConnection(Bike_Service_Locator::getService('Storage')->getWritableConnection());
		}
	}
}
